""" Game actions

Actions are executes for a hex.

"""

import pyciv.resources
import pyciv.worker

class Action(object):
    def __init__(self, name, hex=None, engine = None, 
                 cost = {}, enabled=True, reason="Select hexagon"):
        self.name = name
        self.hex = hex
        self.enabled = enabled
        self.cost = cost
        self.reason = reason
        self.value = 0
        if engine is not None:
            for resource, value in self.cost.iteritems():
                if engine.current_player().resources[resource] < value:
                    self.enabled = False

    def evaluate(self, player, income, engine):
        pass

    def execute(self, engine):
        if self.enabled:
            for resource, value in self.cost.iteritems():
                engine.current_player().resources[resource] -= value
            self._execute(engine)

    def _execute(self, engine):
        pass

    def __str__(self):
        return str((self.name, self.value))

NONE = Action("")

class Influence(Action):
    """ Influence a hex to join your kingdom
    
    """
    
    def __init__(self, hex, enabled, reason):
        Action.__init__(self, "Influence", hex=hex, enabled=enabled, reason=reason)

    def _execute(self, engine):
        engine.state.owner[self.hex] = engine.current_player()
        engine.state.worker[engine.current_hex].ready_for_action = False
        if engine.state.worker[self.hex] is not pyciv.worker.NONE:
            engine.state.worker[self.hex].ready_for_action = False

    def evaluate(self, player, income, engine):
        self.value = 5

class Conquer(Action):
    def __init__(self, hex, enabled, reason):
        Action.__init__(self, "Conquer", hex=hex, enabled=enabled, reason=reason)

    def _execute(self, engine):
        engine.state.owner[self.hex] = engine.current_player()
        worker = engine.state.worker[engine.current_hex]
        engine.state.worker[self.hex] = worker
        engine.state.worker[self.hex].ready_for_action = False
        engine.state.worker[engine.current_hex] = pyciv.worker.NONE

    def evaluate(self, player, income, engine):
        self.value = 3

class Move(Action):
    def __init__(self, hex):
        Action.__init__(self, "Move", hex=hex, reason="Move here")
        
    def _execute(self, engine):
        worker = engine.state.worker[engine.current_hex]
        engine.state.worker[self.hex] = worker
        engine.state.worker[self.hex].ready_for_action = False
        engine.state.worker[engine.current_hex] = pyciv.worker.NONE

    def evaluate(self, player, income, engine):
        current = engine.state.worker[engine.current_hex].income(
            engine.state.terrain[engine.current_hex])
        possible = engine.state.worker[engine.current_hex].income(engine.state.terrain[self.hex])
        difference = pyciv.resources.difference(possible, current)
        self.value = pyciv.resources.reduce(difference)
            
class Switch(Action):
    def __init__(self, hex, enabled, reason):
        Action.__init__(self, "Switch", hex=hex, enabled=enabled, reason=reason)
        
    def _execute(self, engine):
        worker = engine.state.worker[self.hex]
        engine.state.worker[self.hex] = engine.state.worker[engine.current_hex]
        engine.state.worker[engine.current_hex] = worker
        engine.state.worker[self.hex].ready_for_action = False
        engine.state.worker[engine.current_hex].ready_for_action = False

class CreateNewWorker(Action):
    def __init__(self, hex, engine, worker):
        cost = {pyciv.resources.FOOD: 5}
        reason = pyciv.resources.long_string(cost, text="Create for ")
        Action.__init__(self, worker.name, hex=hex, engine=engine, cost=cost, reason=reason)
        self.worker = worker
        
    def _execute(self, engine):
        engine.state.worker[self.hex] = self.worker

    def evaluate(self, player, income, engine):
        if not self.enabled:
            return

        if (player.resources[pyciv.resources.GOLD] + income[pyciv.resources.GOLD] < 
            player.resources[pyciv.resources.FOOD] + income[pyciv.resources.FOOD]):
            if self.worker.income(engine.state.terrain[self.hex]).has_key(pyciv.resources.GOLD):
                self.value = self.worker.income(
                    engine.state.terrain[self.hex])[pyciv.resources.GOLD]
        else:
            if self.worker.income(engine.state.terrain[self.hex]).has_key(pyciv.resources.FOOD):
                self.value = self.worker.income(
                    engine.state.terrain[self.hex])[pyciv.resources.FOOD]
            else:
                if self.worker.income(
                    engine.state.terrain[self.hex]).has_key(pyciv.resources.GOLD):
                    self.value = self.worker.income(
                        engine.state.terrain[self.hex])[pyciv.resources.GOLD]
                

class SellWorker(Action):
    def __init__(self, hex, reason):
        Action.__init__(self, "Sell", hex=hex, reason=reason)
        
    def _execute(self, engine):
        for resource, value in engine.state.worker[engine.current_hex].upkeep().iteritems():
            engine.current_player().resources[resource] += value
        engine.state.worker[engine.current_hex] = pyciv.worker.NONE

    def evaluate(self, player, income, engine):
        if player.resources[pyciv.resources.GOLD] + income[pyciv.resources.GOLD] < 0:
            self.value = engine.state.worker[self.hex].upkeep()[pyciv.resources.GOLD]
        if income[pyciv.resources.FOOD] < 1:
            self.value = engine.state.worker[self.hex].upkeep()[pyciv.resources.FOOD]
